Ext.QuickTips.init();

Ext.ns("Ext.ux");

Ext.ux.SWFUploadDialog = Ext.extend(Ext.Window, {
    title: "SWFUpload Dialog",
    width: 600,
    height: 350,
    layout: "fit",
    modal: true,
    resizable: false,
    closeAction: "hide",
    baseUrl: "",
    grid: null,
    swfupload: null,
    uploadMode: true,
	downloadUrl: "",
	removeUrl: "",
	single: true,
	uploadUrl: "",
	postParams: {},
	filePostName: "file",
	fileSizeLimit: "0",
	fileTypes: "*.*",
	fileTypesDecription: "All Files",
	fileUploadLimit: 0,
	fileQueueLimit: 0,
	fileUploadSuccess: null,
    initComponent: function() {
        this.settings = {
       	    scroll: 20,
       	    startTime: null,
			filesQueued: 0,
			filesCompleted: 0,
       	    scales: {
       	        index:     0.0545,
       	        name:      0.3818,
       	        type:      0.1272,
       	        size:      0.1454,
       	        status:    0.1636,
       	        cancel:    0.0909,
       	        download:  0.0909,
       	        progress:  350.00
       	    },
			ids: {
				add:       Ext.id(),
				upload:    Ext.id(),
				cancel:    Ext.id(),
				clear:     Ext.id(),
				speed:     Ext.id(),
				time:      Ext.id(),
				files:     Ext.id(),
				progress:  Ext.id(),
				swfupload: Ext.id()
			}
        };
        this.tbar = [{
            id: this.settings.ids.add,
            text: "添加文件",
            iconCls: "Add"
        }, "->", {
            id: this.settings.ids.upload,
            text: "上传文件",
            iconCls: "Upload",
            disabled: true,
            scope: this,
            handler: this.onUploadFile
        }, "-", {
            id: this.settings.ids.cancel,
            text: "取消上传",
            iconCls: "Cancel",
            disabled: true,
            scope: this,
            handler: this.onCancelUpload
        }, "-", {
            id: this.settings.ids.clear,
            text: "清空列表",
            iconCls: "Clear",
            scope: this,
            handler: this.onClearAll
        }];
        this.bbar = [new Ext.ProgressBar({
			id: this.settings.ids.progress,
            value: 0,
            width: this.width - this.settings.scales.progress,
            interval: 1000,
            text: "0%"
        }), {
            xtype: "tbtext",
            width: 105,
            text: "平均速度:<span id='" + this.settings.ids.speed +"'></span>"
        }, "-", {
            xtype: "tbtext",
            text: "剩余时间:<span id='" + this.settings.ids.time +"'></span>"
        }, "->", {
            xtype: "tbtext",
            text: "已上传文件数:<span id='" + this.settings.ids.files +"'>0/0</span>"
        }];

        Ext.ux.SWFUploadDialog.superclass.initComponent.call(this);
        this.initGrid();
    	this.add(this.grid);
    	this.setUploadMode(this.uploadMode);
		this.on("afterrender", this.initUpload, this);
		this.on("beforehide", this.isClosable, this);
    },
    initGrid: function() {
    	if (this.grid) {
    		return;
    	}

        this.grid = new Ext.grid.GridPanel({
            border: false,
            columnLines: true,
            stripeRows: true,
            autoExpandColumn: 1,
            loadMask: {msg: "正在加载，请稍候..."},
            colModel: new Ext.grid.ColumnModel([
                new Ext.grid.RowNumberer({
                	width: this.settings.scales.index*this.width
                }), {
                	header: "文件名",
                	dataIndex: "name",
                	width: this.settings.scales.name*this.width
                }, {
                	header: "类型",
                	dataIndex: "type",
                	width: this.settings.scales.type*this.width
                }, {
                	header: "大小",
                	dataIndex: "size",
                	width: this.settings.scales.size*this.width,
                	renderer: Ext.util.Format.fileSize
                }, {
                	header: "状态",
                	dataIndex: "status",
                	width: this.settings.scales.status*this.width,
					renderer: this.formatFileStatus
                },
                new Ext.grid.ActionColumn({
                    width: this.settings.scales.cancel*this.width,
                    align: "center",
                    items: [{
                        icon: this.baseUrl + "swfupload/icons/delete.png",
                        tooltip: "Remove",
						scope: this,
                        handler: function(grid, rowIndex, colIndex) {
							var removeable = true;
							var record = grid.getStore().getAt(rowIndex);
							if (record.data["status"] == SWFUpload.FILE_STATUS.QUEUED) {
								this.swfupload.cancelUpload(record.data["id"]);
							}
							if (record.data["status"] == SWFUpload.FILE_STATUS.COMPLETE) {
								removeable = false;
							}
							
							if (removeable) {
								grid.getStore().remove(grid.getStore().getAt(rowIndex));
								this.updateRowNumber(grid, rowIndex);
							} else {
								this.removeFilesSuccess(grid, rowIndex);
							}
                        }
                    }]
                }),
                new Ext.grid.ActionColumn({
                    width: this.settings.scales.download*this.width,
                    align: "center",
					items: [{
						icon: this.baseUrl + "swfupload/icons/download.png",
						tooltip: "Download",
						scope: this,
						getClass: function(value, metadata, record) {
							if (record.data["status"] != SWFUpload.FILE_STATUS.COMPLETE) {
								return "x-hidden";
							}
						},
						handler: function(grid, rowIndex, colIndex) {
							if (!document.getElementById("ux-download")) {
								var downloadForm = document.createElement('form');
								downloadForm.id = "ux-download";
								downloadForm.name = "ux-download";
								downloadForm.className = 'x-hidden';
								downloadForm.action = this.downloadUrl;
								downloadForm.method = "GET";
								downloadForm.target = "_blank";
								document.body.appendChild(downloadForm);
								
								var file = document.createElement("INPUT");
								file.type= "hidden";
								file.name = "id";
								file.value = grid.getStore().getAt(rowIndex).data["id"];
								downloadForm.appendChild(file);
							}
							document.getElementById("ux-download").submit();
							document.body.removeChild(document.getElementById("ux-download"));
						}
					}]
                })
            ]),
            viewConfig: {
            	scrollOffset: this.settings.scroll,
            	forceFit: false
            },
            store: new Ext.data.Store({
                reader: new Ext.data.JsonReader({}, 
					Ext.data.Record.create(
						{name: "id"},
						{name: "name"},
						{name: "type"},
						{name: "size"},
						{name: "status"}
					)
				)
            })
        });
    },
    initUpload: function() {
        if (this.swfupload) {
            return;
        }
        
        var em = this.getTopToolbar().get(0).el.child("em");
        em.setStyle({
        	position: "relative",
        	display: "block"
        });
        em.createChild({
        	tag: "div",
        	id: this.settings.ids.swfupload
        });
        
        this.swfupload = new SWFUpload({
            debug: false,
            use_query_string: false,
            prevent_swf_caching: false,
        	preserve_relative_urls: false,
            flash_url: this.baseUrl + "swfupload/swfupload.swf",
            flash9_url: this.baseUrl + "swfupload/swfupload_fp9.swf",
            upload_url: this.uploadUrl,
            post_params: this.postParams,
            file_post_name: this.filePostName,
            file_size_limit: this.fileSizeLimit,
            file_types: this.fileTypes,
            file_types_description: this.fileTypesDecription,
            file_upload_limit: this.fileUploadLimit,
            file_queue_limit: this.fileQueueLimit,
            file_dialog_start_handler: this.onFileDialogStart,
            file_queued_handler: this.onFileQueued,
            file_queue_error_handler: this.onFileQueueError,
            file_dialog_complete_handler: this.onFileDialogComplete,
			upload_start_handler: this.onUploadStart,
            upload_progress_handler: this.onUploadProgress,
            upload_error_handler: this.onUploadError,
            upload_success_handler: this.onUploadSuccess,
            upload_complete_handler: this.onUploadComplete,
            button_cursor: SWFUpload.CURSOR.HAND,
            button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
			button_action: (this.single ? SWFUpload.BUTTON_ACTION.SELECT_FILE : SWFUpload.BUTTON_ACTION.SELECT_FILES),
            button_width: em.getWidth(),
            button_height: em.getHeight(),
            button_placeholder_id: this.settings.ids.swfupload,
            custom_settings: {scope_handler: this}
        });
        
        Ext.get(this.swfupload.movieName).setStyle({
        	position: "absolute",
        	top: "0",
        	left: "-2px"
        });
    },
    isClosable: function() {
    	var msg = null;
    	for (var i = 0; i < this.grid.getStore().getCount(); i++) {
    		var record = this.grid.getStore().getAt(i);
    		if (record.data["status"] == SWFUpload.FILE_STATUS.IN_PROGRESS) {
    			msg = "文件正在上传，您确定要关闭吗？";
    			break;
    		} else if (record.data["status"] == SWFUpload.FILE_STATUS.QUEUED) {
                msg = "您有文件未上传，确定要关闭吗？";
                break;
    		}
    	}
    	
    	if (msg != null) {
			var me = this;
    		Ext.Msg.confirm("提示框", msg, function(btn) {
    			if (btn == "yes") {
    				me.onCancelUpload();
    	            me.hide();
    			}
    		});
			return false;
    	}

		return true;
    },
    addPostParam: function(name, value) {
    	this.swfupload.addPostParam(name, value);
    },
	updateRowNumber: function(grid, rowIndex) {
		if (rowIndex < grid.getStore().getCount()) {
			var view = grid.getView();
			for (var i = rowIndex; i < grid.getStore().getCount(); i++) {
				var cell = Ext.fly(view.getCell(i, 0));
				cell.child(".x-grid3-col-numberer").dom.innerHTML = i + 1;
			}
		}
	},
    setUploadMode: function(mode) {
    	this.uploadMode = mode;
    	this.grid.getColumnModel().setHidden(4, !mode);
        this.grid.getColumnModel().setHidden(5, !mode);
        this.grid.getColumnModel().setHidden(6, mode);
        
        if (mode) {
        	this.getTopToolbar().show();
        	this.getBottomToolbar().show();
        } else {
            this.getTopToolbar().hide();
            this.getBottomToolbar().hide();
        }
    },
	loadUploadFile: function(files) {
		this.grid.getStore().removeAll();
		for (var i = 0; i < files.length; i++) {
			this.grid.getStore().add(new Ext.data.Record(files[i]));
		}
	},
	formatFileStatus: function(value) {
		switch(value) {
			case SWFUpload.FILE_STATUS.QUEUED:
				return "等待上传";
			case SWFUpload.FILE_STATUS.IN_PROGRESS:
				return "<span style='color:blue'>上传中...</span>";
			case SWFUpload.FILE_STATUS.ERROR:
				return "<span style='color:red'>上传失败</span>";
			case SWFUpload.FILE_STATUS.COMPLETE:
				return "<span style='color:green'>上传成功</span>";
			case SWFUpload.FILE_STATUS.CANCELLED:
				return "<span style='color:gray'>上传取消</span>";
		}
	},
	setActionDisabled: function(add, upload, cancel, clear) {
		Ext.getCmp(this.settings.ids.add).setDisabled(add);
		this.swfupload.setButtonDisabled(add);
		Ext.getCmp(this.settings.ids.upload).setDisabled(upload);
		Ext.getCmp(this.settings.ids.cancel).setDisabled(cancel);
		Ext.getCmp(this.settings.ids.clear).setDisabled(clear);
	},
	updateFileRecord: function(file, data) {
		this.grid.getStore().each(function(record) {
			if (record.data["id"] == file.id) {
				for (var key in data) {
					record.data[key] = data[key];
				}
				record.commit();
				return;
			}
		});
	},
	clearFilesQueued: function() {
		var stats;
		do {
			stats = this.swfupload.getStats();
			this.swfupload.cancelUpload();
		} while (stats.files_queued !== 0);
		
		this.grid.getStore().each(function(record) {
			if (record.data["status"] == SWFUpload.FILE_STATUS.QUEUED
				|| record.data["status"] == SWFUpload.FILE_STATUS.IN_PROGRESS) {
				record.data["status"] = SWFUpload.FILE_STATUS.CANCELLED;
				record.commit();
			}
		});
	},
	removeFilesSuccess: function(grid, rowIndex) {
		var me = this, ids = [];
		if (Ext.isNumber(rowIndex)) {
			ids.push(grid.getStore().getAt(rowIndex).data["id"]);
		} else {
			grid.getStore().each(function(file) {
				if (file.data["status"] == SWFUpload.FILE_STATUS.COMPLETE) {
					ids.push(file.data["id"]);
				}
			});
		}
		if (ids.length == 0) {
			grid.getStore().removeAll();
			return;
		}
		
		me.getEl().mask("正在删除， 请稍候...");
		Ext.Ajax.request({
			url: this.removeUrl,
			params: {id: Ext.encode(ids)},
			method: "POST",
			callback: function() {me.getEl().unmask();},
			success: function(text) {
				var json = Ext.decode(text.responseText);
				if (json.success) {
					if (Ext.isNumber(rowIndex)) {
						grid.getStore().remove(grid.getStore().getAt(rowIndex));
						me.updateRowNumber(grid, rowIndex);
					} else {
						grid.getStore().removeAll();
					}
				} else {
					Ext.Msg.alert("消息框", "文件删除失败!");
				}
			},
			failure: function(html) {}
		});
	},
	onUploadFile: function() {
		this.setActionDisabled(true, true, false, true);
		this.grid.getEl().mask("正在上传，请稍候...");
		this.swfupload.startUpload();
	},
	onCancelUpload: function() {
		this.swfupload.stopUpload();
		this.clearFilesQueued();
		this.setActionDisabled(false, true, true, false);
		this.grid.getEl().unmask();
	},
	onClearAll: function() {
		this.clearFilesQueued();
		this.removeFilesSuccess(this.grid);
		this.setActionDisabled(false, true, true, false);
	},
	onFileDialogStart: function() {
		var me = this.customSettings.scope_handler;
		if (me.fileUploadLimit == 0) {
			return;
		}
		
		var size = 0;
		me.grid.getStore().each(function(record) {
			if (record.data["status"] == SWFUpload.FILE_STATUS.COMPLETE) {
				size++;
			}
		});
		var stats = this.getStats();
		stats.successful_uploads = size;
		this.setStats(stats);
	},
    onFileQueued: function(file) {
    	var me = this.customSettings.scope_handler;
    	var record = new Ext.data.Record({
    		id: file.id,
    		name: file.name,
    		type: file.type,
    		size: file.size,
    		status: file.filestatus
    	});
    	me.grid.getStore().add(record);
    },
	onFileQueueError: function(file, errorCode, message) {
		var msg = null;
		switch(errorCode) {
		    case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
		    	msg = "上传的文件数超过" + this.settings.file_upload_limit + "个!";break;
		    case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: 
                msg = "文件[" + file.name + "]大小超过" + this.settings.file_size_limit + "!";break;
            case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
                msg = "文件[" + file.name + "]大小为0字节!";break;
            case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: 
                msg = "文件[" + file.name + "]类型不匹配!";break;
            default: msg = "文件[" + file.name + "]未知错误!"
		}
		
		var me = this.customSettings.scope_handler;
		Ext.Msg.alert("消息框", msg);
	},
	onFileDialogComplete: function(numFilesSelected, numFilesQueued) {
		var me = this.customSettings.scope_handler;
		me.settings.filesQueued = this.getStats().files_queued;
		me.settings.filesCompleted = 0;
		Ext.get(me.settings.ids.files).dom.innerHTML = me.settings.filesCompleted + "/" + me.settings.filesQueued;
		
		if (this.getStats().files_queued > 0) {
			me.setActionDisabled(false, false, true, false);
		}
	},
	onUploadStart: function(file) {
		this.addPostParam("param", Ext.encode(file));
		
		var me = this.customSettings.scope_handler;
		me.updateFileRecord.call(me, file, {status: file.filestatus});
		me.settings.startTime = new Date();
	},
	onUploadProgress: function(file, bytesLoaded, bytesTotal) {
		var me = this.customSettings.scope_handler;
		var percent = Math.ceil((bytesLoaded / bytesTotal) * 100) + "%";
		Ext.getCmp(me.settings.ids.progress).updateProgress((bytesLoaded / bytesTotal), percent);
		
		var iTime = new Date();
		var speed = bytesLoaded / (iTime - me.settings.startTime) * 1000;
		var dSpeed = Ext.util.Format.fileSize(Math.ceil(speed)) + "/s";
		if (dSpeed.indexOf("NaN") == -1) {
			Ext.get(me.settings.ids.speed).dom.innerHTML = dSpeed;
		}
		
		var rTime = Math.ceil((bytesTotal - bytesLoaded)/ speed);
		var dTime = new Date(2015, 0, 1, 0, 0, 0);
		dTime.setMilliseconds(dTime.getMilliseconds() + parseInt(rTime)*1000);
		dTime = Ext.util.Format.date(dTime, "H:i:s");
		if (dTime.indexOf("NaN") == -1) {
	        Ext.get(me.settings.ids.time).dom.innerHTML = dTime;
		}
	},
	onUploadError: function(file, errorCode, message) {
		var msg = null;
		switch(errorCode) {
		    case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
            case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
            case SWFUpload.UPLOAD_ERROR.IO_ERROR:
            case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
            case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
            case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
            case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND:
            case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
                msg = "文件[" + file.name + "]上传失败!";break;
            case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
                break;
            case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
            	break;
            default: msg = "文件[" + file.name + "]未知错误!"
		}
		
		if (msg != null) {
	        var me = this.customSettings.scope_handler;
            me.updateFileRecord.call(me, file, {status: file.filestatus});
	        Ext.Msg.alert("消息框", msg);
		}
	},
	onUploadSuccess: function(file, serverData) {
		var me = this.customSettings.scope_handler;
		var json = Ext.decode(serverData);
		if (json.success) {
			me.settings.filesCompleted++;
			me.updateFileRecord.call(me, file, {id: json.id, status: file.filestatus});
			if (Ext.isFunction(me.fileUploadSuccess)) {
				me.fileUploadSuccess(file, serverData);
			}
		} else {
			file.filestatus = SWFUpload.FILE_STATUS.ERROR;
			me.updateFileRecord.call(me, file, {status: file.filestatus});
		}
	},
	onUploadComplete: function(file) {
		var me = this.customSettings.scope_handler;
		if (file.filestatus == SWFUpload.FILE_STATUS.COMPLETE) {
	        Ext.get(me.settings.ids.files).dom.innerHTML = me.settings.filesCompleted + "/" + me.settings.filesQueued;
		}

		if (this.getStats().files_queued > 0) {
			this.startUpload();
		} else {
			me.setActionDisabled(false, true, true, false);
			me.grid.getEl().unmask();
			Ext.getCmp(me.settings.ids.progress).updateProgress(0, "0%");
			Ext.get(me.settings.ids.speed).dom.innerHTML = "";
			Ext.get(me.settings.ids.time).dom.innerHTML = "";
		}
	}
});

Ext.reg("swfupload", Ext.ux.SWFUploadDialog);
